using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using System.IO;
using System.Reflection;

namespace Weazel.Toad.TextEditor.Document
{
	public class HighlightingManager
	{
		List<ResourceSyntaxModeProvider> syntaxModeFileProviders = new List<ResourceSyntaxModeProvider>();
		private static HighlightingManager highlightingManager;
		
		Hashtable highlightingDefinitions = new Hashtable();
		Hashtable extensionsToName = new Hashtable();
		
		public Hashtable HighlightingDefinitions {
			get {
				return highlightingDefinitions;
			}
		}
		
		public static HighlightingManager Manager {
			get {
				return highlightingManager;		
			}
		}
		
		static HighlightingManager()
		{
			highlightingManager = new HighlightingManager();
			highlightingManager.AddSyntaxModeFileProvider(new ResourceSyntaxModeProvider());
		}
		
		public HighlightingManager()
		{
			CreateDefaultHighlighter();
		}
		
		public void AddSyntaxModeFileProvider(ResourceSyntaxModeProvider syntaxModeFileProvider)
		{
			foreach (SyntaxMode syntaxMode in syntaxModeFileProvider.SyntaxModes) {
				highlightingDefinitions[syntaxMode.Name] = new DictionaryEntry(syntaxMode, syntaxModeFileProvider);
				foreach (string extension in syntaxMode.Extensions) {
					extensionsToName[extension.ToUpper()] = syntaxMode.Name;
				}
			}
			if (!syntaxModeFileProviders.Contains(syntaxModeFileProvider)) {
				syntaxModeFileProviders.Add(syntaxModeFileProvider);
			}
		}
		
		public void ReloadSyntaxModes()
		{
			highlightingDefinitions.Clear();
			extensionsToName.Clear();
			CreateDefaultHighlighter();
			foreach (ResourceSyntaxModeProvider provider in syntaxModeFileProviders) {
				AddSyntaxModeFileProvider(provider);
			}
			OnReloadSyntaxHighlighting(EventArgs.Empty);
		}
		
		void CreateDefaultHighlighter()
		{
			Highlighter defaultHighlighter = new Highlighter();
			defaultHighlighter.Extensions = new string[] {};
			defaultHighlighter.Rules.Add(new HighlightRuleSet());
			highlightingDefinitions["Default"] = defaultHighlighter;
		}
		
		Highlighter LoadDefinition(DictionaryEntry entry)
		{
			SyntaxMode              syntaxMode             = (SyntaxMode)entry.Key;
      ResourceSyntaxModeProvider syntaxModeFileProvider = (ResourceSyntaxModeProvider)entry.Value;

      Highlighter highlightingStrategy = HighlightingDefinitionParser.Parse(syntaxMode, syntaxModeFileProvider.GetSyntaxModeFile(syntaxMode));
			highlightingDefinitions[syntaxMode.Name] = highlightingStrategy;
			highlightingStrategy.ResolveReferences();
			
			return highlightingStrategy;
		}
		
		public Highlighter FindHighlighter(string name)
		{
			object def = highlightingDefinitions[name];
			if (def is DictionaryEntry) {
				return LoadDefinition((DictionaryEntry)def);
			}
			return (Highlighter)(def == null ? highlightingDefinitions["Default"] : def);
		}
		
		public Highlighter FindHighlighterForFile(string fileName)
		{
			string highlighterName = (string)extensionsToName[Path.GetExtension(fileName).ToUpper()];
			if (highlighterName != null) {
				object def = highlightingDefinitions[highlighterName];
				if (def is DictionaryEntry) {
					return LoadDefinition((DictionaryEntry)def);
				}
				return (Highlighter)(def == null ? highlightingDefinitions["Default"] : def);
			} else {
				return (Highlighter)highlightingDefinitions["Default"];
			}
		}
		
		protected virtual void OnReloadSyntaxHighlighting(EventArgs e)
		{
			if (ReloadSyntaxHighlighting != null) {
				ReloadSyntaxHighlighting(this, e);
			}
		}
		
		public event EventHandler ReloadSyntaxHighlighting;
	}
}
